<template>
    <transition name="el-zoom-in-center">
        <div class="robot-container" v-show="show">
            <div class="window-container" ref="scrollDiv">
                <div v-if="chatData.length !== 0" v-for="(item, index) in chatData ">
                    <div :class="{
                        'info-card-left': item.role === 'assistant',
                        'info-card-right': item.role === 'user'
                    }">
                        <!--头像  -->
                        <div class="user-avatar" v-if="item.role === 'assistant'">
                            <el-avatar shape="square" :size="50"
                                src="https://i03piccdn.sogoucdn.com/c477d031f53cfe05" />
                        </div>

                        <!-- 内容 -->
                        <div class="user-content">
                            <div v-html="markdown.render(item.content)"></div>
                        </div>

                        <!-- 头像 -->
                        <div class="user-avatar" v-if="item.role !== 'assistant'">
                            <el-avatar shape="square" :size="50" :src="userAvatar" />
                        </div>
                    </div>
                </div>
            </div>

            <div class="bottom">
                <el-input :disabled="isReplying" v-model="content" style="width: 98%;margin-left: 10px;" type="textarea"
                    placeholder="输入提问信息" />
                <div class="send">
                    <el-button :disabled="isReplying" type="primary" style="width: 150px;margin-top: 10px;"
                        :icon="Promotion" @click="handleSend">提问</el-button>
                </div>
            </div>
        </div>
    </transition>
</template>

<script setup>
import { onMounted, ref } from 'vue'
import { Promotion } from '@element-plus/icons-vue'
import axios from 'axios'
import { v4 as uuid4 } from 'uuid'
import store from '@/store';
import MarkdownIt from 'markdown-it';

const markdown = new MarkdownIt()
const userAvatar = ref('https://pic4.zhimg.com/80/v2-5287de47e7e537125b7200fb99b84d53_720w.webp')
const uuid = ref('')
const source = ref(null)
const content = ref('')
const isReplying = ref(false)
const replyContent = ref('')
const show = ref(false)
const chatData = ref([])
const scrollDiv = ref(null)

//滚动到底部
const scrollToBottom = () => {
    //滚动到底部
    let scrollElem = scrollDiv.value;
    scrollElem.scrollTo({ top: scrollElem.scrollHeight, behavior: 'smooth' });
}

/** 生成一个以字母开始的唯一标识符 */
const generateLetterPrefixedId = () => {
    let id = '';
    do {
        // 生成一个UUID并取其前几个字符  
        id = uuid4().substring(0, 8).toUpperCase();
        // 如果第一个字符不是字母，则继续循环  
    }
    while (!/^[a-zA-Z]/.test(id));
    return id;
}

//发送前处理数据
const handleData = () => {
    isReplying.value = true
    chatData.value.push({
        role: 'user',
        content: content.value
    })
    chatData.value.push({
        role: 'assistant',
        content: '正在思考...'
    })
    content.value = ''
    replyContent.value = ''
}

//sse 连接
const SSE = () => {
    if (window.EventSource) {
        // 建立连接
        source.value = new EventSource('http://localhost:8080/open?uuid=' + uuid.value)
        
        /**
         * 连接一旦建立，就会触发open事件
         */
        source.value.onopen = function (e) {
            console.log('建立连接', e)
        }
        /**
         * 客户端收到服务器发来的数据
         */
        source.value.onmessage = function (e) {
            // 滚动到底部
            scrollToBottom()
            console.log(JSON.parse(e.data).output.choices[0].message.content)
            replyContent.value = replyContent.value + JSON.parse(e.data).output.choices[0].message.content
            chatData.value[chatData.value.length - 1].content = replyContent.value
            store.commit('setMessages', chatData.value)
            isReplying.value = false
        }
       
        /**
         * 如果发生通信错误（比如连接中断），就会触发error事件
         */
        source.value.onerror = function (e) {
            if (e.readyState === EventSource.CLOSED) {
                console.log('连接关闭')
            } else {
                console.log(e)
            }
        }
    } else {
        console.log('浏览器不支持SSE')
    }
}

// 发送消息
const handleSend = async () => {
    // 处理数据
    await handleData()
    // 开启sse连接
    SSE()
    // 滚动到底部
    scrollToBottom()
    await axios({
        url: 'http://localhost:8080/push',
        headers: {
            'Content-Type': 'application/json'
        },
        data: {
            'uuid': uuid.value,
            'messages': chatData.value
        },
        method: 'post',
    })
}

onMounted(() => {
    //模仿登录用户的唯一标识
    uuid.value = generateLetterPrefixedId()
    chatData.value = store.getters.getMessages
    show.value = true
})

</script>

<style scoped>
/* 隐藏滚动条 */
::-webkit-scrollbar {
    width: 0;
}

.robot-container {
    margin: 30px auto;
    width: 900px;
    height: 660px;
    border-radius: 10px;
    background-color: rgb(184, 203, 239);
    overflow: hidden;
    box-shadow: 0 2px 3px rgb(0 0 0 / 10%);
    transition: all 0.5s;
    padding: 5px;

    .window-container {
        width: 99%;
        margin: 0 auto;
        margin-top: 10px;
        height: 440px;
        padding: 10px;
        background-color: rgb(245, 245, 245);
        overflow: scroll;

        .info-card-left {
            width: 70%;
            height: 20%;
            display: flex;
            justify-content: left;
            margin-bottom: 10px;

            .user-avatar {
                display: flex;
                align-items: center;
                margin-left: 10px;
                height: 50px;
                box-shadow: 0 2px 3px rgb(0 0 0 / 10%);
            }

            .user-content {
                background-color: white;
                border-radius: 10px;
                box-shadow: 0 2px 3px rgb(0 0 0 / 10%);
                padding: 10px;
                margin-left: 10px;
                font-size: 16px;
                align-items: center;
                display: flex;
            }

            .user-content>>>h1 {
                font-weight: bold;
            }

            .user-content>>>h2 {
                font-weight: bold;
            }

            .user-content>>>h3 {
                font-weight: bold;
            }

            .user-content>>>h4 {
                font-weight: bold;
            }
        }

        .info-card-right {
            width: 70%;
            height: 20%;
            display: flex;
            justify-content: right;
            margin-bottom: 10px;
            margin-left: auto;

            .user-avatar {
                display: flex;
                align-items: center;
                height: 50px;
                margin-right: 10px;
                box-shadow: 0 2px 3px rgb(0 0 0 / 10%);
            }

            .user-content {
                background-color: white;
                border-radius: 10px;
                box-shadow: 0 2px 3px rgb(0 0 0 / 10%);
                padding: 10px;
                margin-right: 10px;
                font-size: 16px;
                background-color: rgb(71, 225, 99);
                align-items: center;
                display: flex;
                text-align: right;
            }
        }
    }

    .bottom {
        width: 99%;
        margin: 0 auto;
        padding-top: 10px;
        height: 180px;
        background-color: rgb(250, 250, 250);

        .send {
            width: 100%;
            height: 50px;
            display: flex;
            justify-content: right;
            align-items: center;
            padding-right: 10px;
        }
    }

    ::v-deep .el-textarea__inner {
        height: 120px;
        font-size: 18px;
    }
}
</style>